#pragma once

#define APFSDS_LIB_BUILD
#include <libapfsds.h>
/* 防止重复 */
#define PTHREADALT_CUSTOM_CONTRUCTOR
/* 四个参数, 对齐至apfsds */
#define SPLK_POOL_SIZE	(65536) /* 支持1023个对象 */
// #define WAITF	schedyield_wait
#define LOCK_MAXFUTURES	(16)

#define APDSARGS_NR	4
#include <ddblk/apds.h>
#include <dbg.h>


/* 自旋等待，当前线程数大于时使用yield */
SAI waitcnt_t waitf_spinyield(void *wptr, void *pwait_ifeq_to, waitcnt_t cnt){
	extern cid_t __apfsds_cur_threads; 
	PARAM_USED(wptr, pwait_ifeq_to);
	/* PAUSE(); */
	if (LIKELY(atm_ld(&__apfsds_cur_threads) <= HDEF_NATIVE_CPU_NR)) PAUSE(); 
	else sched_yield();
	return cnt;
}

NEW_OUFUN(blkwait, spinyield_wait, waitf_spinyield, wakef_spin)

#include <stdlib.h>
#ifdef COREID_BY_RSEQ
	#define APFSDS_COREID_UPDFREQ	(1)
#else
	#define APFSDS_COREID_UPDFREQ	(256)
#endif

/* 不限制大小 */
DEF_LOCKNODE_ALIGNMALLOC(apfsds_obj, -1)


/* install stablized-fin */
#define __APDS2APFSDS(apdsname, name, algalloc, algfree)			\
apfsds_t *apfsds_create##name(void){ apdsname##_t *p = algalloc(sizeof(apdsname##_t)); return apfsds_init(p, sizeof(apdsname##_t)); }\
void apfsds_destroy##name(apfsds_t *l){ void *ptr = apfsds_destruct(l); algfree(ptr, sizeof(apdsname##_t)); }\
apfsds_t *apfsds_init##name(void *ptr, size_t size){ if (!ptr) return (apfsds_t *)NULL; return (apfsds_t *) apdsname##_init(ptr, size); }\
void *apfsds_destruct##name(apfsds_t *l){ if (!l) return NULL; return apdsname##_destruct((apdsname##_t *)l); }\
__attribute__((nonnull (1, 2, 3))) apfsds_future_t *apfsds_fetch##name(apfsds_t *l, apfsds_func_t *func, apfsds_arg_t *args){ return (apfsds_future_t *)apdsname##_fetch((apdsname##_t *)l, func, (apdsarg_t *)args); }\
__attribute__((nonnull (1, 2))) apfsds_return_t apfsds_wait##name(apfsds_t *l, apfsds_future_t *future){ return apdsname##_wait((apdsname##_t *)l, (apdsfuture_t *)future); }\
__attribute__((nonnull (1, 2, 3))) apfsds_return_t apfsds_sync##name(apfsds_t *l, apfsds_func_t *func, apfsds_arg_t *args){ return apdsname##_sync((apdsname##_t *)l, func, (apdsarg_t *)args); }\
__attribute__((nonnull (1, 2))) apfsds_return_t apfsds_sync_fast##name(apfsds_t *l, apfsds_func_t *func, APFSDS_ARGLIST){ apdsarg_t arg = {APFSDS_ARGLIST_USED}; return apdsname##_sync((apdsname##_t *)l, func, &arg); }\
__attribute__((nonnull (1, 2))) apfsds_future_t *apfsds_fetch_fast##name(apfsds_t *l, apfsds_func_t *func, APFSDS_ARGLIST){ apdsarg_t arg = {APFSDS_ARGLIST_USED}; return (apfsds_future_t *)apdsname##_fetch((apdsname##_t *)l, func, &arg); }

/* __attribute__((nonnull (1, 2))) apfsds_return_t apfsds_sync_fast##name(apfsds_t *l, apfsds_func_t *func, apfsds_arg_t args){ return apdsname##_sync((apdsname##_t *)l, func, (apdsarg_t )args); } */

#define APDS2APFSDS(apdsname, algalloc, algfree)		__APDS2APFSDS(apdsname, , algalloc, algfree)
